package com.cqrt.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqrt.dto.WorkItemDTO;
import com.cqrt.entity.ChangeIssueDO;
import com.cqrt.entity.WorkItemDO;
import com.cqrt.mapper.DeptRoleMapper;
import com.cqrt.mapper.RTProjectBoardMapper;
import com.cqrt.mapper.RTTaskMapper;
import com.cqrt.mapper.RtWorkItemMapper;
import com.cqrt.service.RTProjectService;
import com.cqrt.service.RtWorkItemService;
import com.cqrt.vo.WorkItemVO;
import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.type.model.vo.TypeVO;
import com.hustcad.plm.pdm.user.model.dto.OrgExtParamDTO;
import com.hustcad.plm.pdm.user.model.vo.OrgExtVO;
import com.hustcad.plm.pdm.user.service.TyOrgExtService;
import com.hustcad.plm.rpm.model.dto.job.JobStatusUpdateDTO;
import com.hustcad.plm.rpm.model.dto.job.TyppmJobDTO;
import com.hustcad.plm.rpm.model.vo.job.JobExtVO;
import com.hustcad.plm.rpm.service.job.TyppmJobService;
import com.hustcad.plm.rpm.util.beanmapper.BeanMapper;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.PrincipalEntity;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.ppm.model.entity.job.Job;
import lombok.extern.slf4j.Slf4j;
import oracle.sql.CLOB;
import oracle.sql.TIMESTAMP;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.Reader;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RtWorkItemServiceImpl extends ServiceImpl<RtWorkItemMapper,WorkItemDO> implements RtWorkItemService {

    @Resource
    private RtWorkItemMapper rtWorkItemMapper;

    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;

    @Resource
    private DeptRoleMapper deptRoleMapper;

    @Resource
    private TyOrgExtService orgExtService;

    @Resource
    private RTProjectBoardMapper rtProjectBoardMapper;

    @Resource
    private RTProjectService rtProjectService;

    @Resource
    private TyppmJobService typpmJobService;

    @Resource
    private RTTaskMapper rtTaskMapper;

    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;

    @Override
    public List<WorkItemVO> queryWorkItem(WorkItemDTO workItemDTO) {
        UserDO user = TyAccountContext.getUser();
        List<WorkItemVO> workItemVOS = rtWorkItemMapper.queryWorkItem(user.getOid().toString());
        List<WorkItemVO> workItemVOS1 = rtWorkItemMapper.queryWorkItemByCreatorId(user.getOid().toString());
        workItemVOS.addAll(workItemVOS1);

        if (Objects.isNull(workItemDTO)){
            return workItemVOS;
        }
        if (StrUtil.isNotBlank(workItemDTO.getName())){
            workItemVOS=workItemVOS.stream().filter(item -> item.getName().contains(workItemDTO.getName())).collect(Collectors.toList());
        }


        return workItemVOS;
    }

    @Override
    public void insertUserWorkItemLink(WorkItemDTO workItemDTO) {
        LocalDateTime now = LocalDateTime.now();
        UserDO user = TyAccountContext.getUser();
        WorkItemDO workItemDO = new WorkItemDO();
        workItemDO.setAOId(workItemDTO.getAoId());
        workItemDO.setOBId(user.getOid().toString());
        workItemDO.setWorkItemID(workItemDTO.getWorkItemId());
        workItemDO.setCreateStamp(now);
        workItemDO.setUpdateStamp(now);
        workItemDO.setModifyStamp(now);
        workItemDO.setUpdateCount(new BigInteger("0"));
        workItemDO.setOId(snowflakeIdComponent.getInstance().nextId().toString());
        workItemDO.setOType("UserWorkLink");
        save(workItemDO);
    }

    @Override
    public List<Job> queryProjectTask() {
        UserDO user = TyAccountContext.getUser();
        //查询当前用户所在部位的
        List<String> deptIds = deptRoleMapper.selectDeptByUserId(user.getOid().toString());
        if (CollUtil.isEmpty(deptIds)) {
            return Collections.emptyList();
        }
        List<String> allQueryDeptIds=new ArrayList<>();
        Iterator<String> iterator = deptIds.iterator();
        while (iterator.hasNext()) {
            callback(allQueryDeptIds,iterator.next());
        }
        List<OrgExtVO> allMemberOrgsByOrg=new ArrayList<>();
        Iterator<String> iterator1 = allQueryDeptIds.iterator();
        OrgExtParamDTO orgExtParamDTO = new OrgExtParamDTO();
        while (iterator1.hasNext()) {
            orgExtParamDTO.setOtype("ty.inteplm.org.CTyOrg");
            orgExtParamDTO.setOid(new BigInteger(iterator1.next()));
            orgExtService.getMemberOrgsByOrg(orgExtParamDTO);
            allMemberOrgsByOrg.addAll(orgExtService.getMemberOrgsByOrg(orgExtParamDTO));
        }
        List<BigInteger> allDeptID = allMemberOrgsByOrg.stream().map(OrgExtVO::getOid).distinct().collect(Collectors.toList());

        if (CollUtil.isEmpty(allDeptID)){
            return Collections.emptyList();
        }
        List<PrincipalEntity> allMembersByOrg=new ArrayList<>();
        for (BigInteger deptID : allDeptID) {
            List<PrincipalEntity> membersByOrg = orgExtService.getMembersByOrg(deptID);
            if (CollUtil.isNotEmpty(membersByOrg)){
                allMembersByOrg.addAll(membersByOrg);
            }
        }
        List<BigInteger> ids = allMembersByOrg.stream().map(PrincipalEntity::getOid).distinct().collect(
                Collectors.toList());
        ids.add(user.getOid());
        int i = ids.size() / 999;
        List<Job> jobs = new ArrayList<>();
        for (int j = 0; j <= i; j++) {
            if (i==j){
                jobs.addAll(rtProjectBoardMapper.myManageProjectTasks(ids.subList(j * 999,ids.size())));
            }else {
                jobs.addAll(rtProjectBoardMapper.myManageProjectTasks(ids.subList(j * 999, j * 999 + 999)));
            }

        }


        return jobs;
    }

    @Override
    public List<ChangeIssueDO> queryIManageQuestions() {
        /**
         * 查部门
         */
        UserDO user = TyAccountContext.getUser();
        //查询当前用户所在部位的
        List<String> deptIds = deptRoleMapper.selectDeptByUserId(user.getOid().toString());
        if (CollUtil.isEmpty(deptIds)) {
            return Collections.emptyList();
        }
        List<String> allQueryDeptIds=new ArrayList<>();
        Iterator<String> iterator = deptIds.iterator();
        while (iterator.hasNext()) {
            callback(allQueryDeptIds,iterator.next());
        }
        List<OrgExtVO> allMemberOrgsByOrg=new ArrayList<>();
        Iterator<String> iterator1 = allQueryDeptIds.iterator();
        OrgExtParamDTO orgExtParamDTO = new OrgExtParamDTO();
        while (iterator1.hasNext()) {
            orgExtParamDTO.setOtype("ty.inteplm.org.CTyOrg");
            orgExtParamDTO.setOid(new BigInteger(iterator1.next()));
            allMemberOrgsByOrg.addAll(orgExtService.getMemberOrgsByOrg(orgExtParamDTO));
        }
        List<BigInteger> allDeptID = allMemberOrgsByOrg.stream().map(OrgExtVO::getOid).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(allDeptID)){
            return Collections.emptyList();
        }
        List<PrincipalEntity> allMembersByOrg=new ArrayList<>();
        for (BigInteger deptID : allDeptID) {
            List<PrincipalEntity> membersByOrg = orgExtService.getMembersByOrg(deptID);
            if (CollUtil.isNotEmpty(membersByOrg)){
                allMembersByOrg.addAll(membersByOrg);
            }
        }

        List<BigInteger> ids = allMembersByOrg.stream().map(PrincipalEntity::getOid).distinct().collect(
                Collectors.toList());

        int p = ids.size() / 999;
        List<ChangeIssueDO> changeIssueDOS = new ArrayList<>();
        for (int j = 0; j <= p; j++){
            if (p==j){
                changeIssueDOS.addAll(rtProjectBoardMapper.queryIManageQuestions(ids.subList(j * 999,ids.size())));
            }else {
                changeIssueDOS.addAll(rtProjectBoardMapper.queryIManageQuestions(ids.subList(j * 999, j * 999 + 999)));
            }
        }
        changeIssueDOS.addAll(rtProjectBoardMapper.queryIManageQuestions(Arrays.asList(user.getOid())));




        if (CollUtil.isEmpty(changeIssueDOS)) {
            return Collections.emptyList();
        }


        List<String> typeIds = changeIssueDOS
                .stream()
                .map(ChangeIssueDO::getTypeoid)
                .distinct()
                .sorted((x, y) -> {
                    BigInteger x1 = new BigInteger(x);
                    BigInteger y1 = new BigInteger(y);
                    return x1.compareTo(y1);
                })
                .collect(Collectors.toList());
        List<String> typeName = rtProjectBoardMapper.selectTypeByTypeId(typeIds).stream().map(TypeVO::getDisplayName)
                .collect(Collectors.toList());
        HashMap<String, String> map = new HashMap<>();
        for (int i = 0; i < typeIds.size(); i++) {
            map.put(typeIds.get(i), typeName.get(i));
        }

        for (ChangeIssueDO changeIssueDO : changeIssueDOS) {
            changeIssueDO.setTypeDefName(map.get(changeIssueDO.getTypeoid()));
            String objectnumber = changeIssueDO.getObjectnumber();
            Map<String, Object> stringObjectMap = rtProjectService.selectDetsMeasures(objectnumber);
            if (stringObjectMap!=null){
                String name=rtProjectService.selectProjectNameByProjectCode((String) stringObjectMap.get("projectNo"));
                changeIssueDO.setProjectCode((String) stringObjectMap.get("projectNo"));
                changeIssueDO.setProjectName(name);
                changeIssueDO.setPhenomenonDescription(clobToString((CLOB)stringObjectMap.get("phenomenonDescription")));
                changeIssueDO.setOccurrenceStage((String)stringObjectMap.get("occurrenceStage"));
                changeIssueDO.setClosingStage((String)stringObjectMap.get("closingStage"));
                changeIssueDO.setImportance((String)stringObjectMap.get("importance"));
                if (stringObjectMap.get("plannedDate")!=null){
                    changeIssueDO.setPlandate(((TIMESTAMP)stringObjectMap.get("plannedDate")).stringValue());
                }
                changeIssueDO.setPersonResponsible((String) stringObjectMap.get("personResponsible"));
            }
        }
        return changeIssueDOS;
    }
    public static String clobToString(CLOB clob) {
        if (clob == null) {
            return null;
        }

        StringBuilder stringBuilder = new StringBuilder();
        try (Reader reader = clob.getCharacterStream();
             BufferedReader br = new BufferedReader(reader)) {
            String line;
            while ((line = br.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return stringBuilder.toString();
    }

    @Override
    public List<BigInteger> selectOidByPjStatus(List<BigInteger> oids) {
        return rtWorkItemMapper.selectOidByPjStatus(oids);
    }

    public void callback(List<String> allQueryDeptIds,String deptIds){
        allQueryDeptIds.add(deptIds);
        OrgExtParamDTO orgExtParamDTO = new OrgExtParamDTO();
        orgExtParamDTO.setOtype("ty.inteplm.org.CTyOrg");
        orgExtParamDTO.setOid(new BigInteger(deptIds));
        List<OrgExtVO> memberOrgsByOrg = orgExtService.getMemberOrgsByOrg(orgExtParamDTO);
        if (CollUtil.isEmpty(memberOrgsByOrg)){
            return;
        }
        Iterator<OrgExtVO> iterator = memberOrgsByOrg.iterator();
        while (iterator.hasNext()) {
            OrgExtVO next = iterator.next();
            if (next.isHasChildren()){
                callback(allQueryDeptIds,next.getOid().toString());
            }else {
                allQueryDeptIds.add(next.getOid().toString());
            }

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED)
    public void createJob(JobExtVO job) {
        this.typpmJobService.checkCreateJobParams(job);
        TyppmJobDTO map = BeanMapper.map(job, TyppmJobDTO.class);
        this.typpmJobService.insertJob(map, map.getCheckItemList(), map.getDeliverRemoteList(), true);
        JobStatusUpdateDTO jobStatusUpdateDTO = this.typpmJobService.buildJobStatusUpdateDTO(map, "下达");
        this.typpmJobService.setJobState(jobStatusUpdateDTO, "未读");
        this.typpmJobService.calculate(map);
        this.typpmJobService.insertMeetingObjLink(job);
    }

    @Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED)
    @Override
    public void updatePlanStatus(String sourceJobOid, String value) {
        BigInteger activityId = rtTaskMapper.selectActivityIdById(sourceJobOid);
        if(activityId==null){
            return;
        }
        List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();
        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();
        List<IbaDTO> ibaDTOs = new ArrayList<>();
        IbaDTO ibaDTO = new IbaDTO();
        ibaDTO.setValue(value);
        ibaDTO.setKey("ThroughStatus");
        saveObjIBADTO.setObjIbaList(ibaDTOs);
        saveObjIBADTO.setCTyEntityBaseDO(new CTyEntityBaseDO(new BigInteger(sourceJobOid), TableTypeConstrant.TY_JOB_OTYPE));
        typlmAttributeValueService.batchSaveIBAByObjList(objWithIbaList, false);
    }
}
